evalTop_

I have a Maintenance script that will call other scripts from within. In the main script I call a function to open a file to write to for logging information.
During the execution of the scripts I want to print to the same file. I know that I need to use evalTop_...but I'm not sure how to use this function.
I get an "incorrectly concatenated" error when I try this from the main script:

//Log include file
Stream output;

void openFileForWrite(string filename)
{
....

output = write(filename);
.....
....

}
//Main script
openFileForWrite("MaintenenceLog.txt")
evalTop_("output = " output "\n")
...
....
eval_(//call another script here, want to use the same output stream)

What is wrong with this statement?

thanks in advance...
lsand - Wed Apr 27 12:41:06 EDT 2011

Re: evalTop_
llandale - Wed Apr 27 13:20:04 EDT 2011

You cannot concatenate a variable of type "Stream" to a string. What you really want to do it appears is to concatenate the contents of the file; which you can do like this:

string Contents = readFile(NameFile)
string Display = "Contents of file:\n" Contents

Not sure what you are doing but it doesn't seem to me you need to use evalTop_; which would pretty much be so you can defined global functions and variables so various DXL can talk to each other; and in any event doesn't run until this one is finished. Mathias came up with some very clever way to send the address of your Stream to eval_, but I think it will fail for evalTop_ since your script will likely close your stream.

  • Louie

Re: evalTop_
lsand - Wed Apr 27 13:52:01 EDT 2011

llandale - Wed Apr 27 13:20:04 EDT 2011
You cannot concatenate a variable of type "Stream" to a string. What you really want to do it appears is to concatenate the contents of the file; which you can do like this:

string Contents = readFile(NameFile)
string Display = "Contents of file:\n" Contents

Not sure what you are doing but it doesn't seem to me you need to use evalTop_; which would pretty much be so you can defined global functions and variables so various DXL can talk to each other; and in any event doesn't run until this one is finished. Mathias came up with some very clever way to send the address of your Stream to eval_, but I think it will fail for evalTop_ since your script will likely close your stream.

  • Louie

For the life of the main script (which calls other scripts) I'm trying to write to the same log file regardless of which script is executing..i guess from one of your older posts:

https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14285563&#14285563

{code}
Now there IS a use for 'evalTop_' which lets you put variables and functions in the DXL top context, making them available for other DXL programs to use. Haven't actually found a use for that, but surely there are some. Perhaps you want to overload the 'print' function such that instead of outputing to the DXL pane, it outputs it to a file.
{/code}

Re: evalTop_
lsand - Wed Apr 27 13:52:38 EDT 2011

lsand - Wed Apr 27 13:52:01 EDT 2011
For the life of the main script (which calls other scripts) I'm trying to write to the same log file regardless of which script is executing..i guess from one of your older posts:

https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14285563&#14285563

{code}
Now there IS a use for 'evalTop_' which lets you put variables and functions in the DXL top context, making them available for other DXL programs to use. Haven't actually found a use for that, but surely there are some. Perhaps you want to overload the 'print' function such that instead of outputing to the DXL pane, it outputs it to a file.
{/code}

oops...what was the syntax to display ...wasn't {code} {/code}

Re: evalTop_
llandale - Wed Apr 27 16:04:59 EDT 2011

lsand - Wed Apr 27 13:52:01 EDT 2011
For the life of the main script (which calls other scripts) I'm trying to write to the same log file regardless of which script is executing..i guess from one of your older posts:

https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14285563&#14285563

{code}
Now there IS a use for 'evalTop_' which lets you put variables and functions in the DXL top context, making them available for other DXL programs to use. Haven't actually found a use for that, but surely there are some. Perhaps you want to overload the 'print' function such that instead of outputing to the DXL pane, it outputs it to a file.
{/code}

I can see how this main script can invoke other scripts, either using eval_ to #include the other script or to perhaps readFile and sending the text. Not sure what evalTop_ will do, especially for a script that may run multiple times, you will get "already declared in this scope" errors. Are you sending today's LogFileName?

There are other ways to pass data between scripts. I use my own rather complicated DXL_Parameters area in the registry (sibling to Config), but you could use a config file as well. You could also

setenv("XYZ_LogFileName", "c:/LogFile.txt") in the main script, and then
string NameLogFile = getenv("XYZ_LogFileName") in the subordinate script

But then that variable exists in the Config area and it may get confusing.

  • Louie

Proved the concept but never implemented it: script that WANTS to put something in the top context first needs to see if its already there; and if so don't put it again. Finding out if its there involves building a string of code that uses the variable, and check eval_ for errors. If there are errors then it needs to be defined; otherwise it doesn't.

Re: evalTop_
lsand - Wed Apr 27 16:39:07 EDT 2011

llandale - Wed Apr 27 16:04:59 EDT 2011
I can see how this main script can invoke other scripts, either using eval_ to #include the other script or to perhaps readFile and sending the text. Not sure what evalTop_ will do, especially for a script that may run multiple times, you will get "already declared in this scope" errors. Are you sending today's LogFileName?

There are other ways to pass data between scripts. I use my own rather complicated DXL_Parameters area in the registry (sibling to Config), but you could use a config file as well. You could also

setenv("XYZ_LogFileName", "c:/LogFile.txt") in the main script, and then
string NameLogFile = getenv("XYZ_LogFileName") in the subordinate script

But then that variable exists in the Config area and it may get confusing.

  • Louie

Proved the concept but never implemented it: script that WANTS to put something in the top context first needs to see if its already there; and if so don't put it again. Finding out if its there involves building a string of code that uses the variable, and check eval_ for errors. If there are errors then it needs to be defined; otherwise it doesn't.

I do not pass it today's logFileName, rather I just check to see if the file MaintenanceLog.txt exists, if so I append a number , i.e. create MaintenanceLog.1.txt and write to it.

I thought this might work but still get errors, probably because evalTop_ executes after the main script is done. Trying to figure out a way to get around the problem.

evalTop_( "&output = " ((addr_ output) int) "\n")

Re: evalTop_
Mathias Mamsch - Thu Apr 28 07:07:56 EDT 2011

lsand - Wed Apr 27 16:39:07 EDT 2011
I do not pass it today's logFileName, rather I just check to see if the file MaintenanceLog.txt exists, if so I append a number , i.e. create MaintenanceLog.1.txt and write to it.

I thought this might work but still get errors, probably because evalTop_ executes after the main script is done. Trying to figure out a way to get around the problem.

evalTop_( "&output = " ((addr_ output) int) "\n")

Why would you want to use evalTop_ at all? Lets try the simple solutions first why would you not use:
 

Stream y = append(logFileName) 
 
...
 
close y

 


for all of your scripts? This will just append some stuff to the log files. To call the other scripts you can just use #include as long if you don't have the #include inside of a function this will always work:

 

 

 

if (confirm "Start other script?")  {
      #include <otherscript.dxl>
   } else {
      #include <some completly different script.dxl>
   }



If you need to construct the filename of the other script to call at runtime you cannot use include then you would use eval_ (not evalTop_, since this will only run after the first script has ended, with the effect of destroying all the variables closing files, etc.)



 

 

 

 

// don't forget to escape the backslashes here
   string sFileName = "tempFile"
   string myFile = "my\\path\\to\\" sFileName ".dxl" 
   eval_ ("#include <">")



Even in this case you should use append() ... to just append to your log file and not try passing the Stream variable to the eval context. The reason is, that if you pass the stream to your eval_ then your DXL file will not be runnable by itself:



 

 

 

 

// don't forget to escape the backslashes here
string sFileName = "myFile"
string myFile = "my\\path\\to\\" sFileName ".dxl" 
 
Stream theStream = write "C:\\temp\\log.txt"
int iStreamAddress = ((addr_ theStream) int)
string code = "
Stream logFile = addr_ " iStreamAddress "
#include <">"
 
eval_ code



In this case you declare the logFile Stream in the eval context and pass the variable, but that means that myFile will depend on this variable (if it uses it) and not be runnable on its own. Much better would be to just use append from the file.

Hope that clears things up. Regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: evalTop_
Mathias Mamsch - Thu Apr 28 07:20:05 EDT 2011

Mathias Mamsch - Thu Apr 28 07:07:56 EDT 2011

Why would you want to use evalTop_ at all? Lets try the simple solutions first why would you not use:
 

Stream y = append(logFileName) 
 
...
 
close y

 


for all of your scripts? This will just append some stuff to the log files. To call the other scripts you can just use #include as long if you don't have the #include inside of a function this will always work:

 

 

 

if (confirm "Start other script?")  {
      #include <otherscript.dxl>
   } else {
      #include <some completly different script.dxl>
   }



If you need to construct the filename of the other script to call at runtime you cannot use include then you would use eval_ (not evalTop_, since this will only run after the first script has ended, with the effect of destroying all the variables closing files, etc.)



 

 

 

 

// don't forget to escape the backslashes here
   string sFileName = "tempFile"
   string myFile = "my\\path\\to\\" sFileName ".dxl" 
   eval_ ("#include <">")



Even in this case you should use append() ... to just append to your log file and not try passing the Stream variable to the eval context. The reason is, that if you pass the stream to your eval_ then your DXL file will not be runnable by itself:



 

 

 

 

// don't forget to escape the backslashes here
string sFileName = "myFile"
string myFile = "my\\path\\to\\" sFileName ".dxl" 
 
Stream theStream = write "C:\\temp\\log.txt"
int iStreamAddress = ((addr_ theStream) int)
string code = "
Stream logFile = addr_ " iStreamAddress "
#include <">"
 
eval_ code



In this case you declare the logFile Stream in the eval context and pass the variable, but that means that myFile will depend on this variable (if it uses it) and not be runnable on its own. Much better would be to just use append from the file.

Hope that clears things up. Regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Hmm somehow in the posts the #include statements got messed up... Very unusual for the {c o d e} tag... It should be #include <\" myFile ">" (without the backslash, strange with it won't take this code without the backslash) in the examples..

Anyway regarding the top context. One must be very careful with the top context. I found it hard to impossible to get a working mechanism for global variables. Reading global variables works usually fine, but writing to a top level context variable from another DXL context might bring you happy-bug-hunting time, since after your DXL ends, all stuff your DXL context allocated will be freed and it is only a matter of time until the value you wrote to the global variable is overwritten. Therefore evalTop_ is in my opinion only really useful if you want a script to run on top level context, for example to permanently load include files into the top level context, so your scripts will start up faster or if for whatever reason your script wants to mess with stuff that is already in the top context like the DB Explorer. Or as a last reason, if you want to hook any top level functions, for debugging purposes or whatever. Regards, Mathias

Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: evalTop_
lsand - Thu Apr 28 12:25:20 EDT 2011

Mathias Mamsch - Thu Apr 28 07:07:56 EDT 2011

Why would you want to use evalTop_ at all? Lets try the simple solutions first why would you not use:
 

Stream y = append(logFileName) 
 
...
 
close y

 


for all of your scripts? This will just append some stuff to the log files. To call the other scripts you can just use #include as long if you don't have the #include inside of a function this will always work:

 

 

 

if (confirm "Start other script?")  {
      #include <otherscript.dxl>
   } else {
      #include <some completly different script.dxl>
   }



If you need to construct the filename of the other script to call at runtime you cannot use include then you would use eval_ (not evalTop_, since this will only run after the first script has ended, with the effect of destroying all the variables closing files, etc.)



 

 

 

 

// don't forget to escape the backslashes here
   string sFileName = "tempFile"
   string myFile = "my\\path\\to\\" sFileName ".dxl" 
   eval_ ("#include <">")



Even in this case you should use append() ... to just append to your log file and not try passing the Stream variable to the eval context. The reason is, that if you pass the stream to your eval_ then your DXL file will not be runnable by itself:



 

 

 

 

// don't forget to escape the backslashes here
string sFileName = "myFile"
string myFile = "my\\path\\to\\" sFileName ".dxl" 
 
Stream theStream = write "C:\\temp\\log.txt"
int iStreamAddress = ((addr_ theStream) int)
string code = "
Stream logFile = addr_ " iStreamAddress "
#include <">"
 
eval_ code



In this case you declare the logFile Stream in the eval context and pass the variable, but that means that myFile will depend on this variable (if it uses it) and not be runnable on its own. Much better would be to just use append from the file.

Hope that clears things up. Regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

You are right, I should use the append function. Let me see if I am on the right track. What I'm trying to do from the main script is check for fileName, if it already exists, change the filename to fileName.1.txt and then append to that file for the life of the main script (which calls other scripts). Basically I am trying to create a new log file every time the Maintenance script is run. If this is the case, I would still need to pass the newly created fileName to the other DXL scripts so it knows which file to append to and by doing this, it would make my other dxl scripts not standalone.

Otherwise I guess I can have one log file that just gets appended to every time the maintenance script runs, which is nightly.

Re: evalTop_
lsand - Thu Apr 28 12:53:14 EDT 2011

lsand - Thu Apr 28 12:25:20 EDT 2011
You are right, I should use the append function. Let me see if I am on the right track. What I'm trying to do from the main script is check for fileName, if it already exists, change the filename to fileName.1.txt and then append to that file for the life of the main script (which calls other scripts). Basically I am trying to create a new log file every time the Maintenance script is run. If this is the case, I would still need to pass the newly created fileName to the other DXL scripts so it knows which file to append to and by doing this, it would make my other dxl scripts not standalone.

Otherwise I guess I can have one log file that just gets appended to every time the maintenance script runs, which is nightly.

Or just use a constant fileName to append to, and when I close the output stream save the contents into another file and rename it. that way i wouldn't have to pass a filename to the other scripts.

Thanks!

Re: evalTop_
llandale - Thu Apr 28 12:58:28 EDT 2011

Mathias Mamsch - Thu Apr 28 07:20:05 EDT 2011
Hmm somehow in the posts the #include statements got messed up... Very unusual for the {c o d e} tag... It should be #include <\" myFile ">" (without the backslash, strange with it won't take this code without the backslash) in the examples..

Anyway regarding the top context. One must be very careful with the top context. I found it hard to impossible to get a working mechanism for global variables. Reading global variables works usually fine, but writing to a top level context variable from another DXL context might bring you happy-bug-hunting time, since after your DXL ends, all stuff your DXL context allocated will be freed and it is only a matter of time until the value you wrote to the global variable is overwritten. Therefore evalTop_ is in my opinion only really useful if you want a script to run on top level context, for example to permanently load include files into the top level context, so your scripts will start up faster or if for whatever reason your script wants to mess with stuff that is already in the top context like the DB Explorer. Or as a last reason, if you want to hook any top level functions, for debugging purposes or whatever. Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Yes, playing with the top context is like playing with an unloaded gun. lol